package cn.vehicle.biz.schedule;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.vehicle.biz.event.VehicleChangeEvent;
import cn.vehicle.domains.bo.QueryCommonVehicleBo;
import cn.vehicle.domains.bo.QueryTransportVehicleBo;
import cn.vehicle.domains.entity.CommonVehicleEntity;
import cn.vehicle.domains.entity.TransportVehicleEntity;
import cn.vehicle.enums.GovUploadStatus;
import cn.vehicle.service.CommonVehicleService;
import cn.vehicle.service.TransportVehicleService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 天津监管数据补偿定时任务
 * <p>
 * 定期扫描近一小时内上传政府平台失败的车辆数据（普通车辆与运输车辆），
 * 并重新触发上报事件进行数据补偿。
 * </p>
 *
 * <p>主要功能：</p>
 * <ul>
 *   <li>每 5 分钟执行一次；</li>
 *   <li>筛选前 1 小时至前 5 分钟内上报失败的数据；</li>
 *   <li>通过事件机制 {@link VehicleChangeEvent} 重新触发数据上报。</li>
 * </ul>
 */
@Component
@Slf4j
public class TjSchedule {

    @Resource
    private TransportVehicleService transportVehicleService;

    @Resource
    private CommonVehicleService commonVehicleService;

    @Resource
    private ApplicationEventPublisher applicationEventPublisher;

    /**
     * 定时补偿上报失败的车辆数据
     * <p>
     * 任务每 5 分钟执行一次，查询前 1 小时至前 5 分钟内上报政府平台失败的记录，
     * 并发布 {@link VehicleChangeEvent} 事件重新执行上报逻辑。
     * </p>
     */
    //@Scheduled(cron = "0 0/5 * * * ? ")
    @Scheduled(fixedRate = 1, timeUnit = TimeUnit.MINUTES)
    public void compensateUploadGovFail() {
        // 构造运输车辆查询条件：时间范围为前1小时至前5分钟

        log.info("定时补偿上报失败车辆数据开始执行");
        QueryTransportVehicleBo queryTransportVehicleBo = new QueryTransportVehicleBo();
        queryTransportVehicleBo.setStartTime(DateUtil.offset(new Date(), DateField.HOUR, -1));
        queryTransportVehicleBo.setEndTime(DateUtil.offset(new Date(), DateField.MINUTE, -5));

        // 设置上报状态过滤条件，仅筛选需要补偿的数据
        queryTransportVehicleBo.setGovUploadStatusList(GovUploadStatus.needCompensateStatus());

        // 查询符合条件的运输车辆列表
        List<TransportVehicleEntity> transportVehicleEntityList = transportVehicleService.selectTransportVehicleList(queryTransportVehicleBo);

        log.info("查询到{}个需要补偿的运输车辆", transportVehicleEntityList.size());

        // 若未查询到任何需补偿的记录，则直接结束任务
        if (CollectionUtil.isEmpty(transportVehicleEntityList)) {
            return;
        }

        // 提取运输车辆ID列表，用于查询对应的普通车辆
        List<Long> list = transportVehicleEntityList.stream().map(TransportVehicleEntity::getId).toList();

        // 构造普通车辆查询条件，按运输车辆ID关联查询
        QueryCommonVehicleBo queryCommonVehicleBo = new QueryCommonVehicleBo();
        queryCommonVehicleBo.setAssIds(list);
        List<CommonVehicleEntity> commonVehicleEntityList = commonVehicleService.selectCommonVehicleList(queryCommonVehicleBo);

        // 遍历普通车辆列表，依次发布车辆上报事件以触发补偿逻辑
        for (CommonVehicleEntity commonVehicleEntity : commonVehicleEntityList) {
            // 创建车辆变更事件对象，携带普通车辆ID作为补偿标识
            VehicleChangeEvent vehicleChangeEvent = new VehicleChangeEvent(this, commonVehicleEntity.getId());
            // 通过 Spring 事件机制发布事件，触发重新上报流程
            applicationEventPublisher.publishEvent(vehicleChangeEvent);
        }
    }


}
